// Copyright (c) 2013 Doug Binks
// 
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
// 
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
// 
// 1. The origin of this software must not be misrepresented; you must not
//    claim that you wrote the original software. If you use this software
//    in a product, an acknowledgement in the product documentation would be
//    appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//    misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.

#include "TaskScheduler.h"

#include <stdio.h>

using namespace enki;

TaskScheduler g_TS;


struct PinnedTaskHelloWorld : IPinnedTask
{
    PinnedTaskHelloWorld()
        : IPinnedTask(0) // set pinned thread to 0
    {}
    void Execute() override
    { 
        printf("This will run on the main thread\n");
    }
};

struct ParallelTaskSet : ITaskSet
{
    PinnedTaskHelloWorld pinnedTask;
    void ExecuteRange( TaskSetPartition range_, uint32_t threadnum_ ) override
    {
        g_TS.AddPinnedTask( &pinnedTask );

        printf("This could run on any thread, currently thread %d\n", threadnum_);

        g_TS.WaitforTask( &pinnedTask );
    }
};

static const int REPEATS        = 5;

int main(int argc, const char * argv[])
{
    g_TS.Initialize();

    for( int run = 0; run< REPEATS; ++run )
    {

        ParallelTaskSet task;
        g_TS.AddTaskSetToPipe( &task );

        printf("Task %d added\n", run );

        // RunPinnedTasks must be called on main thread to run any pinned tasks for that thread.
        // Tasking threads automatically do this in their task loop.
        g_TS.RunPinnedTasks(); 

        g_TS.WaitforTask( &task);
    }

    return 0;
}
